#pragma once

#define REGISTERUNIFORMINSTRUCTION(name, func) static bool ___init = Game::RegisterUniformInstruction(name, func)

#include <map>
#include <vector>
#include "Pointer.h"
#include "HashedString.h"

class Uniform
{
public:
	enum Type
	{
		VEC1 = 1,
		VEC2,
		VEC3,
		VEC4,
		MATRIX2,
		MATRIX3,
		MATRIX4,
	};
	typedef std::vector<Uniform> Vector_t;
	typedef std::map<HashedString, Uniform> Map_t;
	typedef std::pair<HashedString, Uniform> Pair_t;

	void* location;
	HashedString name;
	Type type;
	unsigned int elements;
};

class UniformData
{
public:
	typedef std::vector<Pointer<UniformData>> Vector_t;
	typedef std::map<HashedString, Pointer<UniformData>> Map_t;
	typedef std::pair<HashedString, Pointer<UniformData>> Pair_t;

	bool transpose;
	unsigned int count;
	Uniform::Type type;
	void* data;
};

class IUniformInstruction
{
public:
	typedef Pointer<IUniformInstruction> (*CreateFunction)( );
	typedef std::map<HashedString, CreateFunction> CreatorMap_t;
	typedef std::pair<HashedString, CreateFunction> CreatorPair_t;

	typedef std::map<HashedString, Pointer<IUniformInstruction>> Map_t;
	typedef std::pair<HashedString, Pointer<IUniformInstruction>> Pair_t;

	unsigned int count;
	Uniform::Type type;
	virtual const HashedString& Type() = 0;
	virtual UniformData operator()( void* data ) = 0;
};